<template>
  <div class="model-container">
    <h2>艺标画板</h2>
    <div class="drawing-tools">
      <el-button-group>
        <el-button 
          v-for="tool in tools" 
          :key="tool.name"
          :type="currentTool === tool.name ? 'primary' : 'default'"
          @click="setTool(tool.name)"
        >
          {{ tool.label }}
        </el-button>
      </el-button-group>
      <el-color-picker
        v-model="currentColor"
        show-alpha
        :predefine="predefineColors"
        @active-change="handleColorChange"
      />
      <el-slider
        v-model="lineWidth"
        :min="1"
        :max="20"
        style="width: 200px; margin-left: 20px;"
      />
      <el-button 
        type="warning" 
        @click="undo" 
        :disabled="!canUndo"
      >
        撤销
      </el-button>
      <el-popover
        placement="bottom"
        :width="300"
        trigger="click"
        v-if="currentTool === 'emoji'"
      >
        <template #reference>
          <el-button type="primary" :class="{ active: currentTool === 'emoji' }">选择表情</el-button>
        </template>
        <div class="emoji-settings">
          <div class="emoji-size-control">
            <span>表情大小：</span>
            <el-slider
              v-model="emojiSize"
              :min="20"
              :max="100"
              style="width: 200px;"
            />
          </div>
          <div class="emoji-container">
            <div 
              v-for="emoji in emojis" 
              :key="emoji"
              class="emoji-item"
              @click="selectEmoji(emoji)"
            >
              {{ emoji }}
            </div>
          </div>
        </div>
      </el-popover>
      <el-button type="danger" @click="clearCanvas">清空画板</el-button>
      <el-button type="success" @click="saveDrawing">保存图像</el-button>
    </div>
    <div class="canvas-container">
      <canvas 
        ref="canvas" 
        width="800" 
        height="600"
        @mousedown="startDrawing"
        @mousemove="draw"
        @mouseup="stopDrawing"
        @mouseleave="stopDrawing"
      ></canvas>
    </div>

    <!-- 保存的图片展示区域 -->
    <div class="saved-drawings" v-if="savedImages.length > 0">
      <h3>已保存的图像</h3>
      <div class="image-grid">
        <div v-for="(image, index) in savedImages" :key="index" class="saved-image-item">
          <el-image 
            :src="image" 
            fit="contain"
            :preview-src-list="[image]"
          />
          <div class="image-actions">
            <el-button type="primary" size="small" @click="uploadImage(image, index)">上传图片</el-button>
            <el-button type="info" size="small">继续编辑</el-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, watch, computed } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'

export default {
  name: 'ModelView',
  setup() {
    const baseUrl = 'http://localhost:8081' // 基础URL
    const canvas = ref(null)
    const ctx = ref(null)
    const isDrawing = ref(false)
    const lastX = ref(0)
    const lastY = ref(0)
    const currentColor = ref('#000000')
    const lineWidth = ref(5)
    const currentTool = ref('pencil')
    const savedImages = ref([])
    const emojiSize = ref(30)
    const selectedEmoji = ref(null)
    const canvasEmojis = ref([])
    const undoStack = ref([])
    const currentState = ref(null)

    const canUndo = computed(() => undoStack.value.length > 0)

    const saveState = () => {
      if (!ctx.value || !canvas.value) return
      
      const state = {
        imageData: ctx.value.getImageData(0, 0, canvas.value.width, canvas.value.height),
        emojis: JSON.parse(JSON.stringify(canvasEmojis.value))
      }
      undoStack.value.push(state)
      
      // 限制撤销栈的大小
      if (undoStack.value.length > 20) {
        undoStack.value.shift()
      }
    }

    const undo = () => {
      if (!canUndo.value) return

      const previousState = undoStack.value.pop()
      if (previousState) {
        ctx.value.putImageData(previousState.imageData, 0, 0)
        canvasEmojis.value = previousState.emojis
        redrawCanvas()
      }
    }

    const tools = [
      { name: 'pencil', label: '铅笔' },
      { name: 'line', label: '直线' },
      { name: 'rectangle', label: '矩形' },
      { name: 'circle', label: '圆形' },
      { name: 'eraser', label: '橡皮擦' },
      { name: 'emoji', label: '表情' }
    ]

    const emojis = [
      '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣',
      '😊', '😇', '🙂', '🙃', '😉', '😌', '😍', '🥰',
      '😘', '😗', '😙', '😚', '😋', '😛', '😝', '😜',
      '🤪', '🤨', '🧐', '🤓', '😎', '🤩', '🥳', '😏',
      '❤️', '💛', '💚', '💙', '💜', '🖤', '💔', '✨',
      '⭐', '🌟', '💫', '💥', '💢', '💦', '💨', '🕊️'
    ]

    const predefineColors = [
      '#ff4500',
      '#ff8c00',
      '#ffd700',
      '#90ee90',
      '#00ced1',
      '#1e90ff',
      '#c71585',
      '#000000',
      '#ffffff'
    ]

    const selectEmoji = (emoji) => {
      selectedEmoji.value = emoji
      currentTool.value = 'emoji'
    }

    const redrawCanvas = () => {
      if (!ctx.value) return
      
      // 如果有临时绘制状态，先恢复它
      if (currentState.value) {
        ctx.value.putImageData(currentState.value, 0, 0)
      }
      
      // 绘制所有 emoji
      canvasEmojis.value.forEach(emojiObj => {
        ctx.value.font = `${emojiObj.size}px Arial`
        ctx.value.textAlign = 'center'
        ctx.value.textBaseline = 'middle'
        ctx.value.fillText(emojiObj.emoji, emojiObj.x, emojiObj.y)
      })
    }

    const startDrawing = (e) => {
      isDrawing.value = true
      const rect = canvas.value.getBoundingClientRect()
      lastX.value = e.clientX - rect.left
      lastY.value = e.clientY - rect.top

      if (currentTool.value === 'emoji' && selectedEmoji.value) {
        saveState()
        canvasEmojis.value.push({
          emoji: selectedEmoji.value,
          x: lastX.value,
          y: lastY.value,
          size: emojiSize.value,
          isDragging: false
        })
        redrawCanvas()
        isDrawing.value = false
        return
      }

      // 为非自由绘制工具保存画布状态
      if (currentTool.value !== 'pencil' && currentTool.value !== 'eraser') {
        currentState.value = ctx.value.getImageData(0, 0, canvas.value.width, canvas.value.height)
        ctx.value.save()
      }
    }

    const draw = (e) => {
      if (!isDrawing.value) return

      const rect = canvas.value.getBoundingClientRect()
      const x = e.clientX - rect.left
      const y = e.clientY - rect.top

      if (currentTool.value === 'emoji') {
        return
      }

      ctx.value.lineWidth = lineWidth.value
      ctx.value.strokeStyle = currentTool.value === 'eraser' ? '#ffffff' : currentColor.value

      switch (currentTool.value) {
        case 'pencil':
        case 'eraser':
          ctx.value.beginPath()
          ctx.value.moveTo(lastX.value, lastY.value)
          ctx.value.lineTo(x, y)
          ctx.value.stroke()
          lastX.value = x
          lastY.value = y
          break

        case 'line':
          if (currentState.value) {
            ctx.value.putImageData(currentState.value, 0, 0)
          }
          ctx.value.beginPath()
          ctx.value.moveTo(lastX.value, lastY.value)
          ctx.value.lineTo(x, y)
          ctx.value.stroke()
          break

        case 'rectangle':
          if (currentState.value) {
            ctx.value.putImageData(currentState.value, 0, 0)
          }
          const width = x - lastX.value
          const height = y - lastY.value
          ctx.value.beginPath()
          ctx.value.strokeRect(lastX.value, lastY.value, width, height)
          break

        case 'circle':
          if (currentState.value) {
            ctx.value.putImageData(currentState.value, 0, 0)
          }
          const radius = Math.sqrt(
            Math.pow(x - lastX.value, 2) + Math.pow(y - lastY.value, 2)
          )
          ctx.value.beginPath()
          ctx.value.arc(lastX.value, lastY.value, radius, 0, Math.PI * 2)
          ctx.value.stroke()
          break
      }
    }

    const stopDrawing = () => {
      if (!isDrawing.value) return
      
      if (currentTool.value === 'emoji') {
        return
      }

      // 在绘制结束时保存状态
      if (currentTool.value === 'pencil' || currentTool.value === 'eraser') {
        // 自由绘制工具在每次绘制结束时保存状态
        saveState()
      } else {
        // 其他工具在完成绘制时保存状态
        saveState()
        currentState.value = null
      }

      isDrawing.value = false
    }

    const handleColorChange = (color) => {
      currentColor.value = color
      if (ctx.value) {
        ctx.value.strokeStyle = color
      }
    }

    const setTool = (tool) => {
      currentTool.value = tool
      if (ctx.value) {
        ctx.value.lineWidth = lineWidth.value
        ctx.value.strokeStyle = currentColor.value
      }
    }

    const clearCanvas = () => {
      saveState() // 保存清除前的状态
      ctx.value.fillStyle = '#ffffff'
      ctx.value.fillRect(0, 0, canvas.value.width, canvas.value.height)
      ctx.value.strokeStyle = currentColor.value
      canvasEmojis.value = []
    }

    const saveDrawing = () => {
      const imageUrl = canvas.value.toDataURL('image/png')
      savedImages.value.push(imageUrl)
      clearCanvas()
      ElMessage.success('图像已保存')
    }

    const generateUniqueFileName = () => {
      const timestamp = new Date().getTime()
      const random = Math.floor(Math.random() * 10000)
      return `drawing_${timestamp}_${random}.png`
    }

    const base64ToFile = (base64String, fileName) => {
      const arr = base64String.split(',')
      const mime = arr[0].match(/:(.*?);/)[1]
      const bstr = atob(arr[1])
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], fileName, { type: mime })
    }

    const uploadImage = async (imageUrl, index) => {
      try {
        const fileName = generateUniqueFileName()
        const file = base64ToFile(imageUrl, fileName)
        
        // 创建 FormData
        const formData = new FormData()
        formData.append('file', file)
        
        // 上传文件
        const uploadResponse = await axios.post(baseUrl + '/common/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
        
        if (uploadResponse.data.code === 200) {
          // 创建图片记录
          const requestData = {
            createimgName: fileName,
            createimgUrl: uploadResponse.data.url
          }
          
          const response = await axios.post(baseUrl + '/AI/createimg', requestData)
          
          if (response.data.code === 200) {
            ElMessage.success('图片上传成功')
          } else {
            throw new Error(response.data.msg || '创建图片记录失败')
          }
        } else {
          throw new Error(uploadResponse.data.msg || '文件上传失败')
        }
      } catch (error) {
        ElMessage.error(error.message || '上传失败')
      }
    }

    onMounted(() => {
      ctx.value = canvas.value.getContext('2d')
      initCanvas()
    })

    const initCanvas = () => {
      if (!ctx.value) return
      ctx.value.strokeStyle = currentColor.value
      ctx.value.lineWidth = lineWidth.value
      ctx.value.lineCap = 'round'
      ctx.value.lineJoin = 'round'
      
      ctx.value.fillStyle = '#ffffff'
      ctx.value.fillRect(0, 0, canvas.value.width, canvas.value.height)
    }

    watch(lineWidth, (newWidth) => {
      if (ctx.value) {
        ctx.value.lineWidth = newWidth
      }
    })

    return {
      canvas,
      currentColor,
      lineWidth,
      tools,
      currentTool,
      predefineColors,
      savedImages,
      emojis,
      emojiSize,
      canUndo,
      startDrawing,
      draw,
      stopDrawing,
      handleColorChange,
      setTool,
      clearCanvas,
      saveDrawing,
      selectEmoji,
      undo,
      uploadImage,
    }
  }
}
</script>

<style scoped>
.model-container {
  padding: 20px;
}

.drawing-tools {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.canvas-container {
  display: flex;
  justify-content: center;
  margin-bottom: 30px;
}

canvas {
  border: 1px solid #dcdfe6;
  background-color: white;
  cursor: crosshair;
}

.saved-drawings {
  margin-top: 30px;
}

.saved-drawings h3 {
  margin-bottom: 20px;
  color: #303133;
}

.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
}

.saved-image-item {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
  background: white;
}

.saved-image-item .el-image {
  width: 100%;
  height: 200px;
  margin-bottom: 10px;
}

.image-actions {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
}

.image-actions .el-button {
  flex: 1;
}

.emoji-settings {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.emoji-size-control {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 10px;
}

.emoji-container {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 8px;
  padding: 10px;
  max-height: 200px;
  overflow-y: auto;
}

.emoji-item {
  font-size: 24px;
  cursor: pointer;
  text-align: center;
  padding: 5px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.emoji-item:hover {
  background-color: #f5f7fa;
}

.active {
  background-color: #409eff;
  color: white;
}
</style>